package cn.xdf.docscan

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.ComponentActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import cn.xdf.docscan.ui.QuadrilateralViewAdapter
import cn.xdf.docscan.util.TempStore
import cn.xdf.docscan.view.QuadrilateralView
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
 * DocScanner测试Activity
 * 完整的文档扫描功能测试
 */
class DocScannerTestActivity : ComponentActivity() {
    
    companion object {
        private const val TAG = "DocScannerTestActivity"
        private const val REQUEST_CODE_PERMISSIONS = 10
        private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
    }
    
    // UI组件
    private lateinit var previewView: PreviewView
    private lateinit var quadrilateralView: QuadrilateralView
    // DocumentOverlayView 已移除
    
    // CameraX组件
    private var imageCapture: ImageCapture? = null
    private var imageAnalysis: ImageAnalysis? = null
    private lateinit var cameraExecutor: ExecutorService
    
    // DocScanner组件
    private lateinit var docScannerController: DocScannerController
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_doc_scanner_test)
        
        // 初始化UI
        initViews()
        
        // 检查权限
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
        }
        
        // 初始化DocScanner
        initDocScanner()
        
        // 初始化相机执行器
        cameraExecutor = Executors.newSingleThreadExecutor()
    }
    
    /**
     * 初始化UI组件
     */
    private fun initViews() {
        previewView = findViewById<PreviewView>(R.id.preview_view)
        quadrilateralView = findViewById(R.id.quadrilateral_view)
        // 已移除 DocumentOverlayView
        findViewById<View>(R.id.capture_button).setOnClickListener {
            try {
                val corners = docScannerController.getLastDetectedCorners()
                if (corners == null || corners.size != 4) {
                    Log.w(TAG, "无有效角点，使用裁剪缓存回退")
                    docScannerController.capture()
                } else {
                    takeFullResolutionAndCrop(corners)
                }
            } catch (e: Exception) {
                Log.e(TAG, "capture failed", e)
                docScannerController.capture()
            }
        }
    }
    
    /**
     * 初始化DocScanner
     */
    private fun initDocScanner() {
        docScannerController = DocScannerController.Builder(this)
            .setQuadOverlay(QuadrilateralViewAdapter(quadrilateralView))
            // 不再传 doc overlay
            .enableAutoCapture(false)
            .build()
        docScannerController.initialize(object : DocScannerController.DocScannerCallback {
            override fun onInitialized() {
                Log.d(TAG, "✅ DocScanner初始化完成")
                // removed toast
            }
            
            override fun onDetectionStarted() {
                Log.d(TAG, "🔍 开始检测")
                // removed toast
            }
            
            override fun onDetectionResult(detections: List<DetectionStateMachine.Detection>) {
                Log.d(TAG, "📄 检测到 ${detections.size} 个文档")
                // removed toast
            }
            
            override fun onCroppedFramesReceived(bitmaps: List<Bitmap>) {
                Log.d(TAG, "✂️ 收到 ${bitmaps.size} 个裁剪帧")
                // removed toast
            }
            
            override fun onOriginalFrameReceived(bitmap: Bitmap) {
                Log.d(TAG, "🖼️ 收到原始帧: ${bitmap.width}x${bitmap.height}")
                // removed toast
            }
            
            override fun onCaptureResult(captured: List<Bitmap>) {
                Log.d(TAG, "📸 捕获完成: ${captured.size} 个图像")
                val intent = android.content.Intent(this@DocScannerTestActivity, Class.forName("cn.xdf.docscan.EnhanceTestActivity"))
                val uri = TempStore.storeBitmapAndGetUri(this@DocScannerTestActivity, captured[0])
                intent.putExtra("rectified_uri", uri.toString())
                startActivity(intent)
            }
            
            override fun onRectifiedBitmapReady(bitmap: Bitmap) {

            }
            
            override fun onError(error: String) {
                Log.e(TAG, "❌ DocScanner错误: $error")
                // removed toast
            }
        })
    }
    
    /**
     * 启动相机
     */
    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        
        cameraProviderFuture.addListener({
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
            
            // 预览用例
            val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(previewView.surfaceProvider)
                }
            
            // 图像分析用例
            imageAnalysis = ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, ImageAnalyzer())
                }
            
            // 图像捕获用例
            imageCapture = ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build()
            
            try {
                // 解绑所有用例
                cameraProvider.unbindAll()
                
                // 绑定用例到相机
                val camera = cameraProvider.bindToLifecycle(
                    this,
                    CameraSelector.DEFAULT_BACK_CAMERA,
                    preview,
                    imageAnalysis,
                    imageCapture
                )

                // 记录预览尺寸用于坐标映射
                previewView.post {
                    val width = previewView.width
                    val height = previewView.height
                    Log.d(TAG, "预览视图尺寸: ${width}x${height}")
                }
                
                Log.d(TAG, "✅ 相机启动成功")
                
            } catch (exc: Exception) {
                Log.e(TAG, "❌ 相机绑定失败", exc)
            }
            
        }, ContextCompat.getMainExecutor(this))
    }
    
    /**
     * 图像分析器
     */
    private inner class ImageAnalyzer : ImageAnalysis.Analyzer {
        override fun analyze(imageProxy: ImageProxy) {
            try {
                // 将ImageProxy转换为Bitmap
                val bitmap = imageProxyToBitmap(imageProxy)
                
                if (bitmap != null) {
                    // 同步更新坐标变换矩阵
                    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
                    // 使用实际的裁剪矩形，避免宽度偏差
                    val crop = imageProxy.cropRect
                    docScannerController.updateImageTransform(
                        imageWidth = imageProxy.width,
                        imageHeight = imageProxy.height,
                        rotationDegrees = rotationDegrees,
                        previewWidth = previewView.width,
                        previewHeight = previewView.height,
                        cropLeft = crop.left,
                        cropTop = crop.top,
                        cropRight = crop.right,
                        cropBottom = crop.bottom
                    )
                    // 处理图像
                    docScannerController.processBitmap(bitmap)
                    
                    // 释放Bitmap
                    bitmap.recycle()
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "❌ 图像分析失败", e)
            } finally {
                // 关闭ImageProxy
                imageProxy.close()
            }
        }
        
        /**
         * 将ImageProxy转换为Bitmap
         */
        private fun imageProxyToBitmap(imageProxy: ImageProxy): Bitmap? {
            return try {
                when (imageProxy.format) {
                    ImageFormat.YUV_420_888 -> {
                        // 简单的YUV到RGB转换
                        val yuvToRgbConverter = YuvToRgbConverter(this@DocScannerTestActivity)
                        val bitmap = Bitmap.createBitmap(imageProxy.width, imageProxy.height, Bitmap.Config.ARGB_8888)
                        yuvToRgbConverter.yuvToRgb(imageProxy, bitmap)
                        bitmap
                    }
                    ImageFormat.JPEG -> {
                        val buffer = imageProxy.planes[0].buffer
                        val bytes = ByteArray(buffer.remaining())
                        buffer.get(bytes)
                        BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
                    }
                    else -> {
                        Log.w(TAG, "不支持的图像格式: ${imageProxy.format}")
                        null
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "转换ImageProxy为Bitmap失败", e)
                null
            }
        }
    }

    private fun takeFullResolutionAndCrop(cornersPreview: List<android.graphics.PointF>) {
        val capture = imageCapture ?: return docScannerController.capture()
        // 同步 targetRotation 到预览
        capture.targetRotation = this@DocScannerTestActivity.windowManager.defaultDisplay.rotation
        capture.takePicture(ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageCapturedCallback() {
            override fun onCaptureSuccess(image: ImageProxy) {
                try {
                    val bitmap = decodeCapturedImage(image) ?: return docScannerController.capture()
                    // 将预览角点映射回原始拍照尺寸坐标
                    val mapped = mapPreviewCornersToImage(bitmap.width, bitmap.height, cornersPreview)
                    val rectified = cn.xdf.docscan.util.ImageWarp.warpQuadToRect(bitmap, mapped)
                    if (rectified != null) {
                        callbackOnCapture(listOf(rectified))
                    } else {
                        docScannerController.capture()
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "full-res capture crop failed", e)
                    docScannerController.capture()
                } finally {
                    image.close()
                }
            }

            override fun onError(exception: ImageCaptureException) {
                Log.e(TAG, "ImageCapture error", exception)
                docScannerController.capture()
            }
        })
    }

    private fun decodeCapturedImage(image: ImageProxy): Bitmap? {
        return try {
            when (image.format) {
                ImageFormat.YUV_420_888 -> {
                    val bmp = Bitmap.createBitmap(image.width, image.height, Bitmap.Config.ARGB_8888)
                    YuvToRgbConverter(this).yuvToRgb(image, bmp)
                    bmp
                }
                ImageFormat.JPEG -> {
                    val buffer = image.planes[0].buffer
                    val bytes = ByteArray(buffer.remaining())
                    buffer.get(bytes)
                    BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
                }
                else -> {
                    Log.w(TAG, "capture format not supported: ${image.format}")
                    null
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "decodeCapturedImage failed", e)
            null
        }
    }

    private fun mapPreviewCornersToImage(imgW: Int, imgH: Int, cornersPreview: List<android.graphics.PointF>): List<android.graphics.PointF> {
        // 复用控制器的预览矩阵的逆变换：将预览坐标映射回图像（拍照）坐标
        val m = android.graphics.Matrix()
        m.set(docScannerControllerImageMatrix())
        val inv = android.graphics.Matrix()
        m.invert(inv)
        val pts = FloatArray(8)
        for (i in 0 until 4) {
            pts[i * 2] = cornersPreview[i].x
            pts[i * 2 + 1] = cornersPreview[i].y
        }
        inv.mapPoints(pts)
        // 分辨率缩放：analysis image -> capture image
        val (srcW, srcH) = docScannerControllerImageSize()
        val sx = if (srcW > 0) imgW.toFloat() / srcW else 1f
        val sy = if (srcH > 0) imgH.toFloat() / srcH else 1f
        return listOf(
            android.graphics.PointF(pts[0] * sx, pts[1] * sy),
            android.graphics.PointF(pts[2] * sx, pts[3] * sy),
            android.graphics.PointF(pts[4] * sx, pts[5] * sy),
            android.graphics.PointF(pts[6] * sx, pts[7] * sy)
        )
    }

    // 暴露控制器当前的预览矩阵（通过反射读取 imageTransform）
    private fun docScannerControllerImageMatrix(): android.graphics.Matrix {
        return try {
            val f = DocScannerController::class.java.getDeclaredField("imageTransform")
            f.isAccessible = true
            val v = f.get(docScannerController) as ImageTransformationInfo
            v.transformationMatrix
        } catch (e: Exception) {
            android.graphics.Matrix()
        }
    }

    private fun docScannerControllerImageSize(): Pair<Int, Int> {
        return try {
            val f = DocScannerController::class.java.getDeclaredField("imageTransform")
            f.isAccessible = true
            val v = f.get(docScannerController) as ImageTransformationInfo
            Pair(v.imageWidth, v.imageHeight)
        } catch (e: Exception) {
            Pair(0, 0)
        }
    }

    private fun callbackOnCapture(bitmaps: List<Bitmap>) {
        // 直接复用已有回调逻辑入口
        object : DocScannerController.DocScannerCallback {
            override fun onInitialized() {}
            override fun onDetectionStarted() {}
            override fun onDetectionResult(detections: List<DetectionStateMachine.Detection>) {}
            override fun onCroppedFramesReceived(bitmaps: List<Bitmap>) {}
            override fun onOriginalFrameReceived(bitmap: Bitmap) {}
            override fun onCaptureResult(captured: List<Bitmap>) {}
            override fun onError(error: String) {}
        }
        // 直接跳增强页
        val intent = android.content.Intent(this, Class.forName("cn.xdf.docscan.EnhanceTestActivity"))
        val uri = cn.xdf.docscan.util.TempStore.storeBitmapAndGetUri(this, bitmaps[0])
        intent.putExtra("rectified_uri", uri.toString())
        startActivity(intent)
    }
    
    /**
     * 检查权限
     */
    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
    }
    
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                startCamera()
            } else {
                // removed toast
                finish()
            }
        }
    }
    
    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
        docScannerController.release()
    }
}

/**
 * YUV到RGB转换器
 */
class YuvToRgbConverter(private val context: android.content.Context) {
    private val yuvToRgbMatrix = android.graphics.ColorMatrix()
    
    init {
        yuvToRgbMatrix.setSaturation(0f)
    }
    
    fun yuvToRgb(image: ImageProxy, output: Bitmap) {
        // 简单的YUV到RGB转换实现
        val yBuffer = image.planes[0].buffer
        val uBuffer = image.planes[1].buffer
        val vBuffer = image.planes[2].buffer
        
        val ySize = yBuffer.remaining()
        val uSize = uBuffer.remaining()
        val vSize = vBuffer.remaining()
        
        val nv21 = ByteArray(ySize + uSize + vSize)
        
        yBuffer.get(nv21, 0, ySize)
        vBuffer.get(nv21, ySize, vSize)
        uBuffer.get(nv21, ySize + vSize, uSize)
        
        val yuvImage = android.graphics.YuvImage(nv21, ImageFormat.NV21, image.width, image.height, null)
        val out = java.io.ByteArrayOutputStream()
        yuvImage.compressToJpeg(android.graphics.Rect(0, 0, image.width, image.height), 100, out)
        val imageBytes = out.toByteArray()
        val bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
        
        val canvas = android.graphics.Canvas(output)
        canvas.drawBitmap(bitmap, 0f, 0f, null)
        bitmap.recycle()
    }
} 